package com.xz.coursearrange.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xz.coursearrange.common.ServerResponse;
import com.xz.coursearrange.dao.ClassroomDao;
import com.xz.coursearrange.dao.CoursePlanDao;
import com.xz.coursearrange.entity.*;
import com.xz.coursearrange.entity.request.UpdateCourseRequest;
import com.xz.coursearrange.entity.response.CoursePlanVo;
import com.xz.coursearrange.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 */
@Service
@Slf4j
public class CoursePlanServiceImpl extends ServiceImpl<CoursePlanDao, CoursePlan> implements CoursePlanService {

    @Resource
    private CourseInfoService courseInfoService;
    @Resource
    private ClassroomService classroomService;
    @Resource
    private TeacherService teacherService;
    @Resource
    private ClassroomDao classroomDao;
    @Resource
    private CoursePlanDao coursePlanDao;
    @Resource
    private TeachbuildInfoService teachbuildInfoService;
    @Resource
    private RedissonClient redissonClient;

    /**
     * 根据班级编号查询课表
     *
     * @param classNo 班级编号
     */
    @Override
    public ServerResponse queryCoursePlanByClassNo(String classNo) {
        // 构建查询条件：班级编号为指定值，并按照classTime字段升序排序
        LambdaQueryWrapper<CoursePlan> queryWrapper = new LambdaQueryWrapper<CoursePlan>()
                .eq(CoursePlan::getClassNo, classNo) // 筛选指定班级编号
                .orderByAsc(CoursePlan::getClassTime); // 按上课时间升序排序

        // 执行查询
        List<CoursePlan> coursePlanList = coursePlanDao.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(coursePlanList)) {
            return ServerResponse.ofError("该班级没有课表");
        }

        // 过滤出教师编号
        List<String> teacherNos = coursePlanList.stream().map(CoursePlan::getTeacherNo).distinct().collect(Collectors.toList());
        // 过滤出课程编号
        List<String> courseNos = coursePlanList.stream().map(CoursePlan::getCourseNo).distinct().collect(Collectors.toList());

        // 查询教师信息
        List<Teacher> teachers = teacherService.list(new LambdaQueryWrapper<Teacher>().in(Teacher::getTeacherNo, teacherNos));
        // 查询课程信息
        List<CourseInfo> courseInfos = courseInfoService.list(new LambdaQueryWrapper<CourseInfo>().in(CourseInfo::getCourseNo, courseNos));

        List<CoursePlanVo> coursePlanVos = new LinkedList<>();
        coursePlanList.forEach(v -> {
            // v 转换成 CoursePlanVo 对象
            CoursePlanVo coursePlanVo = new CoursePlanVo();
            BeanUtils.copyProperties(v, coursePlanVo);

            // 根据教师编号找到教师名称
            teachers.stream().filter(t -> t.getTeacherNo().equals(v.getTeacherNo())).findFirst().ifPresent(t -> coursePlanVo.setRealname(t.getRealname()));
            courseInfos.stream().filter(c -> c.getCourseNo().equals(v.getCourseNo())).findFirst().ifPresent(c -> coursePlanVo.setCourseName(c.getCourseName()));
            coursePlanVos.add(coursePlanVo);
        });

        return ServerResponse.ofSuccess(coursePlanVos);
    }

    /**
     * 根据讲师编号查询课表
     * todo 未完待续
     *
     * @param teacherNo 讲师（教师）编号
     */
    @Override
    public ServerResponse queryCoursePlanByTeacherNo(String teacherNo) {
        // 构建查询条件：教师编号为指定值，并按照classTime字段升序排序
        LambdaQueryWrapper<CoursePlan> queryWrapper = new LambdaQueryWrapper<CoursePlan>()
                .eq(CoursePlan::getTeacherNo, teacherNo) // 筛选指定教师编号
                .orderByAsc(CoursePlan::getClassTime); // 按上课时间升序排序

        // 执行查询
        List<CoursePlan> coursePlanList = coursePlanDao.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(coursePlanList)) {
            return ServerResponse.ofError("该教师没有排课信息");
        }

        // 过滤出课程编号
        List<String> courseNos = coursePlanList.stream().map(CoursePlan::getCourseNo).distinct().collect(Collectors.toList());

        // 查询课程信息
        List<CourseInfo> courseInfos = courseInfoService.list(new LambdaQueryWrapper<CourseInfo>().in(CourseInfo::getCourseNo, courseNos));

        // 直接转换CoursePlan到CoursePlanVo，假设CoursePlan中已包含必要的展示信息
        List<CoursePlanVo> coursePlanVos = new LinkedList<>();
        coursePlanList.stream()
                .map(coursePlan -> {
                    CoursePlanVo vo = new CoursePlanVo();
                    BeanUtils.copyProperties(coursePlan, vo);

                    courseInfos.stream().filter(c -> c.getCourseNo().equals(coursePlan.getCourseNo())).findFirst().ifPresent(c -> vo.setCourseName(c.getCourseName()));
                    coursePlanVos.add(vo);
                    return vo;
                })
                .collect(Collectors.toList());

        return ServerResponse.ofSuccess(coursePlanVos);
    }

    @Override
    public ServerResponse queryAllSemester() {
        QueryWrapper<CoursePlan> queryWrapper=new QueryWrapper<>();
        queryWrapper.select("DISTINCT semester");
        final List<String> list = this.listObjs(queryWrapper, o -> o.toString());

        return ServerResponse.ofSuccess(list);
    }

    /**
     * 根据教室编号查询课表
     *
     * @param classroomNo 教室编号
     */
    @Override
    public ServerResponse queryCoursePlanByClassroomNo(String classroomNo) {
        // 构建查询条件：教室编号为指定值，并按照classTime字段升序排序
        LambdaQueryWrapper<CoursePlan> queryWrapper = new LambdaQueryWrapper<CoursePlan>()
                .eq(CoursePlan::getClassroomNo, classroomNo) // 筛选指定教室编号
                .orderByAsc(CoursePlan::getClassTime); // 按上课时间升序排序

        // 执行查询
        List<CoursePlan> coursePlanList = coursePlanDao.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(coursePlanList)) {
            return ServerResponse.ofError("该教室没有排课信息");
        }

        // 过滤出班级编号、教师编号
        List<String> classNos = coursePlanList.stream().map(CoursePlan::getClassNo).distinct().collect(Collectors.toList());
        List<String> teacherNos = coursePlanList.stream().map(CoursePlan::getTeacherNo).distinct().collect(Collectors.toList());
        // 过滤出课程编号
        List<String> courseNos = coursePlanList.stream().map(CoursePlan::getCourseNo).distinct().collect(Collectors.toList());

        // 查询班级信息（假设需要，根据实际业务调整）
        // List<ClassInfo> classInfos = classInfoService.list(new LambdaQueryWrapper<ClassInfo>().in(ClassInfo::getClassNo, classNos));

        // 查询教师信息
        List<Teacher> teachers = teacherService.list(new LambdaQueryWrapper<Teacher>().in(Teacher::getTeacherNo, teacherNos));

        // 查询课程信息
        List<CourseInfo> courseInfos = courseInfoService.list(new LambdaQueryWrapper<CourseInfo>().in(CourseInfo::getCourseNo, courseNos));

        // 由于课程编号在原始逻辑中未直接用于展示信息的转换，这里假设课程信息不需要额外查询或已包含在CoursePlan中

        List<CoursePlanVo> coursePlanVos = new LinkedList<>();
        coursePlanList.forEach(v -> {
            CoursePlanVo coursePlanVo = new CoursePlanVo();
            BeanUtils.copyProperties(v, coursePlanVo);

            // 根据教师编号找到教师名称
            teachers.stream().filter(t -> t.getTeacherNo().equals(v.getTeacherNo())).findFirst().ifPresent(t -> coursePlanVo.setRealname(t.getRealname()));
            courseInfos.stream().filter(c -> c.getCourseNo().equals(v.getCourseNo())).findFirst().ifPresent(c -> coursePlanVo.setCourseName(c.getCourseName()));
            // 假设课程名称已经包含在CoursePlan实体中，无需额外查询
            coursePlanVos.add(coursePlanVo);
        });

        return ServerResponse.ofSuccess(coursePlanVos);
    }


    //  弃用-------------------------
//    @Override
//    public List<CoursePlan> redlist() {
//        Gson gson = new Gson();
//        String redisKey = "course:plane:recommend:data";
//        RList<String> rList = redissonClient.getList(redisKey);
//
//        // 尝试从Redis获取数据
//        if (!rList.isEmpty()) {
//            log.info("Using cached data from Redis.");
//            List<String> jsonList = rList.readAll();
//            Type coursePlanListType = new TypeToken<List<CoursePlan>>() {
//            }.getType();
//            try {
//                List<CoursePlan> coursePlans = gson.fromJson(jsonList.get(0), coursePlanListType); // 假设存储的是单个字符串包含整个列表的JSON
//                return coursePlans;
//            } catch (Exception e) {
//                log.error("Error deserializing CoursePlan list from JSON", e);
//            }
//        }
//
//        log.info("Data not found in Redis, querying from database.");
//        List<CoursePlan> resultList = list(); // 原有的数据库查询逻辑
//
//        // 如果从数据库获取到了数据，同步到Redis
//        if (!resultList.isEmpty()) {
//            String json = gson.toJson(resultList);
//            rList.clear(); // 清除旧数据
//            rList.add(json);
//            redissonClient.getBucket(redisKey).expire(600000, TimeUnit.SECONDS); // 设置过期时间
//        }
//
//        return resultList;
//    }

    @Override
    public ServerResponse unUseClassTime(Integer id) {
        // 所有上课时间
        ArrayList<String> allClassTime = new ArrayList<>();
        for (int i = 0; i < 40; i++) {
            allClassTime.add(String.format("%02d", i + 1));
        }

        // 已经使用的时间
        ArrayList<String> useClassTime = new ArrayList<>();

        // 获取该班级下是所有上课时间
        CoursePlan coursePlan = this.getById(id);
        String classNo = coursePlan.getClassNo();
        String classTime1 = coursePlan.getClassTime();
        QueryWrapper<CoursePlan> coursePlanQueryWrapper = new QueryWrapper<>();
        coursePlanQueryWrapper.eq("class_no", classNo);
        List<CoursePlan> list = this.list(coursePlanQueryWrapper);
        for (CoursePlan coursePlan1 : list) {
            String classTime = coursePlan1.getClassTime();
            useClassTime.add(classTime);
        }
        if(allClassTime.removeAll(useClassTime)){
            allClassTime.add(classTime1);
            return ServerResponse.ofSuccess(allClassTime);
        }else {
            return ServerResponse.ofError("获取失败");
        }
    }

    /**
     * 获取可选教室
     * @param id
     * @param classTime
     * @return
     */
    @Override
    public ServerResponse unUseClassroom(Integer id, String classTime) {
        CoursePlan coursePlan = this.getById(id);
        String classroomNo = coursePlan.getClassroomNo();

        // 获取课程属性
        String courseNo = coursePlan.getCourseNo();
        QueryWrapper<CourseInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("course_no", courseNo);
        CourseInfo course = courseInfoService.getOne(queryWrapper);
        String courseAttr = course.getCourseAttr();

        if (!"03".equals(courseAttr) && !"04".equals(courseAttr)){
            courseAttr = "01"; // 普通教室
        }

        // 获取对应属性下的所有教室
        QueryWrapper<Classroom> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("attr", courseAttr);
        List<Classroom> classrooms = classroomService.list(queryWrapper1);
        List<String> classroomNos = classrooms.stream()
                .map(Classroom::getClassroomNo)
                .collect(Collectors.toList());


        // 对应时间下被使用的教室
        QueryWrapper<CoursePlan> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.eq("class_time", classTime);
        List<CoursePlan> courseplanlist = this.list(queryWrapper2);

        for (CoursePlan coursePlan1 : courseplanlist){
            classroomNos.remove(coursePlan1.getClassroomNo());
        }

        classroomNos.add(0, classroomNo);
        return ServerResponse.ofSuccess(classroomNos);
    }

    @Override
    public ServerResponse unUseClassTimeByClassNo(String classNo) {
        // 所有上课时间
        ArrayList<String> allClassTime = new ArrayList<>();
        for (int i = 0; i < 40; i++) {
            allClassTime.add(String.format("%02d", i + 1));
        }

        // 已经使用的时间
        ArrayList<String> useClassTime = new ArrayList<>();

        QueryWrapper<CoursePlan> coursePlanQueryWrapper = new QueryWrapper<>();
        coursePlanQueryWrapper.eq("class_no", classNo);
        List<CoursePlan> list = this.list(coursePlanQueryWrapper);

        for (CoursePlan coursePlan1 : list) {
            String classTime = coursePlan1.getClassTime();
            useClassTime.add(classTime);
        }

        if(allClassTime.removeAll(useClassTime)){
            return ServerResponse.ofSuccess(allClassTime);
        }else {
            return ServerResponse.ofError("获取失败");
        }
    }

    @Override
    public ServerResponse unUseTeacherByClassTime(String classTime) {
        QueryWrapper<CoursePlan> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("class_time", classTime);
        List<CoursePlan> coursePlansList = this.list(queryWrapper);
        List<String> collect = coursePlansList.stream().map(CoursePlan::getTeacherNo).collect(Collectors.toList());
        if(collect.isEmpty()){
            return ServerResponse.ofSuccess(teacherService.list());
        }else {
            QueryWrapper<Teacher> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.notIn("teacher_no", collect);
            return ServerResponse.ofSuccess(teacherService.list(queryWrapper1));
        }
    }

    @Override
    public ServerResponse unUseClassroomByClassTimeAndCourseAttr(String courseNo, String classTime) {
        // 根据课程编号获取课程属性
        QueryWrapper<CourseInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("course_no", courseNo);
        CourseInfo one = courseInfoService.getOne(queryWrapper);
        String courseAttr = one.getCourseAttr();

        if (!"03".equals(courseAttr) && !"04".equals(courseAttr)){
            courseAttr = "01"; // 普通教室
        }

        List<Classroom> classrooms = classroomDao.selectByClassTimeAndCourseNo(classTime, courseAttr);
        if (classrooms == null || classrooms.isEmpty()){
            return ServerResponse.ofError("错误");
        }

        return ServerResponse.ofSuccess(classrooms);
    }
    public HashSet<Integer> selectionOptionalLessonByTeacherId(Integer id){
        List<String> classTime = coursePlanDao.selectTeacherTime(id);
        HashSet<Integer> set=new HashSet<Integer>();
        for (String s : classTime) {
            set.add(Integer.parseInt(s));
        }
        return set;
    }
    //查询空闲时间
    public ServerResponse selectionOptionalLessonByClassId(Integer classId,Integer teacherId){
        List<String> feelTime=new ArrayList<>();
        HashSet<Integer> teacherTime = selectionOptionalLessonByTeacherId(teacherId);
        List<String> classTime = coursePlanDao.selectClassTime(classId);
        for (String s:classTime){
            teacherTime.add(Integer.parseInt(s));
        }
        for(int i=1;i<=40;i++){
            if(!teacherTime.contains(i)){
                String s;
                if (i<10){
                    s="0"+i;
                }else {
                    s=i+"";
                }
                feelTime.add(s);
            }
        }
        return ServerResponse.ofSuccess(feelTime);
    }

    @Override
    public ServerResponse selectionClassRoomByGrade(String grade,String lessonPlan) {
        List<String> classRooms = coursePlanDao.selectionClassRoomGrade(grade);
        List<String> room = new ArrayList<>();
        for (String s : classRooms){
            if(coursePlanDao.selectionCLassRoomTimeNull(s,lessonPlan)!=null){
                room.add(s);
            }
        }
        return ServerResponse.ofSuccess(room);
    }
    @Override
    public ServerResponse updateCourse(UpdateCourseRequest request){
        if(coursePlanDao.updateCourseTime(request)==1){
            return ServerResponse.ofSuccess(1);
        }else {
            return ServerResponse.ofError(0);
        }
    }
}
